package org.polyforms.di.spring.schema;

import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.xml.XmlReaderContext;
import org.springframework.context.annotation.ClassPathBeanDefinitionScanner;
import org.springframework.context.annotation.ComponentScanBeanDefinitionParser;

/**
 * Extension of {@link ComponentScanBeanDefinitionParser} to support instantiation of interfaces and abstract classed.
 * 
 * It requires {@link AbstractMethodOverrideProcessor} in spring container.
 * 
 * @author Kuisong Tong
 * @since 1.0
 */
public final class PolyformsComponentScanBeanDefinitionParser extends ComponentScanBeanDefinitionParser {
    /**
     * {@inheritDoc}
     */
    @Override
    protected ClassPathBeanDefinitionScanner createScanner(final XmlReaderContext readerContext,
            final boolean useDefaultFilters) {
        return new PolyformsClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters);
    }

    private static final class PolyformsClassPathBeanDefinitionScanner extends ClassPathBeanDefinitionScanner {
        private PolyformsClassPathBeanDefinitionScanner(final BeanDefinitionRegistry registry,
                final boolean useDefaultFilters) {
            super(registry, useDefaultFilters);
        }

        @Override
        protected boolean isCandidateComponent(final AnnotatedBeanDefinition beanDefinition) {
            return beanDefinition.getMetadata().isIndependent();
        }
    }
}
